/*************************************************************************************************
# Copyright (C), 20xx-20xx, xxx. Co., Ltd.
# File Name :		adc.c
# Author : decorn		Version : V1.0		Date : 2017-08-10
# Description :
#	ADC BSP
# Others :
#	None
# Function List :
#	adc_pw_monitor_init
#	adc_get_raw_dat
#	adc_calc_voltage
#	adc_calc_tempreture
# History :
#	1. Author : decorn		Version : V1.0		Date : 2017-08-10
#		Modification: Create
#	2.
#************************************************************************************************/
#define FILE_ID_ADC

#include "st_adc.h"

static volatile uint16_t g_u16a_adc_dma_buf[10u] __attribute__((section("ADC_BUF"), zero_init));

//volatile uint16_t g_u16_vref_cal	= 0u;
//volatile uint16_t g_u16_temp_cal	= 0u;
	
/*************************************************************************************************
#  Function : adc_init
#  Descriptions :
#	Initialize Power monitor ADC
#  Input :
#	None
#  Output :
#	None
#  Return :
#	None
#  Others :
#	None
#  History :
#  1. Author : decorn		  Version : V1.0	  Date : 2017-08-10
#	Modification: Create
#  2. ��
#---------------------------------------------------------*/
void adc_init(void)//adc初始化
{
	GPIO_InitTypeDef  GPIO_InitStructure;

	ADC_InitTypeDef		ADC_InitStructure;
	DMA_InitTypeDef		DMA_InitStructure;

	/* Enable  GPIOA clock */
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = (uint32_t)(GPIO_Pin_2|GPIO_Pin_3);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; 
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	/* ADC1 DeInit */
	ADC_DeInit(ADC1);
	/* ADC1 Periph clock enable */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	/* DMA1 clock enable */
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
	/* DMA1 Channel1 Config */
	DMA_DeInit(DMA1_Channel1);
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)0x40012440;
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)g_u16a_adc_dma_buf;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize = 5u;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel1, &DMA_InitStructure);

	/* ADC DMA request in circular mode */
	ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);

	/* Initialize ADC structure */
	ADC_StructInit(&ADC_InitStructure);

	/* Configure the ADC1 in continous mode withe a resolutuion equal to 12 bits  */
	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 
	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward; /* ADC_ScanDirection_Backward; */
	ADC_Init(ADC1, &ADC_InitStructure); 

	/* Convert the ADC1 temperature sensor	with 55.5 Cycles as sampling time   16*/ 
	ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor , ADC_SampleTime_55_5Cycles);  
	ADC_TempSensorCmd(ENABLE);

	/* Convert the ADC1 Vref  with 55.5 Cycles as sampling time  17*/ 
	ADC_ChannelConfig(ADC1, ADC_Channel_Vrefint , ADC_SampleTime_55_5Cycles); 
	ADC_VrefintCmd(ENABLE);

	ADC_ChannelConfig(ADC1, ADC_Channel_2  , ADC_SampleTime_55_5Cycles);   //2
	ADC_ChannelConfig(ADC1, ADC_Channel_3  , ADC_SampleTime_55_5Cycles);   //3
	ADC_ChannelConfig(ADC1, ADC_Channel_8  , ADC_SampleTime_55_5Cycles);   //8 

	/* ADC Calibration */
	//g_u16_temp_cal	= *(volatile uint16_t *)(0x1FFFF7B8);
	//g_u16_vref_cal	= *(volatile uint16_t *)(0X1FFFF7BA);
	(void)ADC_GetCalibrationFactor(ADC1);

	/* DMA1 Channel1 enable */
	DMA_Cmd(DMA1_Channel1, ENABLE);
	/* Enable ADC_DMA */
	ADC_DMACmd(ADC1, ENABLE);

	/* Enable ADC1 */
	ADC_Cmd(ADC1, ENABLE);

	/* Wait the ADRDY falg */
	while(RESET == ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY))
	{
		;
	}

	/* ADC1 regular Software Start Conv */ 
	ADC_StartOfConversion(ADC1);//ADC启动采样就一直在采样
}

/*************************************************************************************************
#  Function : adc_get_raw_dat
#  Descriptions :
#	Get the conversion result of the ADC
#  Input :
#	None
#  Output :
#	u16p_dat	: Conversion result(raw), 
   [0]->CH2-线圈电压, [1]->CH3-电源电压, [2]->CH8-半导体诊断, [3]->Temperature, [4]->Vref.
#  Return :
#	None
#  Others :
#	None
#  History :
#  1. Author : decorn		Version : V1.0		Date : 2017-08-10
#	Modification: Create
#  2. ��
#---------------------------------------------------------*/
void adc_get_raw_dat(uint16_t *u16p_dat)//读取ADC采样结构，10个数组，用到5个，后续可以修改数组大小
{
	uint8_t u8lv_i	= 0u;
	
	for(u8lv_i = 0u; u8lv_i < 10u; u8lv_i ++)
	{
		*u16p_dat = g_u16a_adc_dma_buf[u8lv_i];
		u16p_dat ++;
	}
}

